package chatServer.controller;
import java.io.*;
import java.net.*;
import java.util.*;

import chat.model.*;

/**
*   A Chat management program that accompanies the Chat Client program (Task 2 onwards).  Its main function is to allow easy 
*   communication to and from the Client Group.
*
* @author Tung Nguyen, Trung V Hoang, Rob Bernard, Justin Semmel
* @see java.util.Observable
* @since September 2012 
*/	
public class ChatServerController implements ObserverChatServer
{
/*  'chatServerController.java'  created by: Team N3 for Swinburne Uni HET715s2/Dr. Recep Ulusoy, 2/10/2012 v0.0 (final)
*   =================================================================================
*
*   A Chat management program that accompanies the Chat Client program (Task 2 onwards).  Its main function is to allow easy 
*   communication to and from the Client Group.
*
*   When stimulated by an input packet, it generates a TCP Socket connection on Port 6666 of this PC, and manages packet 
*   distribution from this Server to the Chat group.  Also updates Chat Group with the Client.  
*
*       NOTE:   a simple diagnostic log of Server activity is available on the CLI Window display.
*   
*   	Java Code Writers:  		Tung Nguyen and Trung Hoang      
*	Embedded documentation:              Rob Bernard
*	JavaDoc development:		Justin Semmel
*
*  VERBAL (STEPWISE) FLOWCHART :
*
*	1.  Constructor for Server
*	2.  Client Connection Loop             
*	3.  Add Client to list  
*	4.  Remove client from list
*	5.  Message Output request 
*	6.  Message output
*
*
*  CLASSES CALLED:  ServerSocket, chatServerConnectionList, chatUserList, broadcastMessage.
*  ==============    Class and Method summary.  (done by Justin in JavaDocs?)
*/
	private ServerSocket serverSocket;
	private ArrayList <ChatUser> chatUserList;
	private ArrayList <ChatServerConnection> chatServerConnectionList;
	
	public String username = "";
		
	public ChatServerController()
	{
		try
		{
			chatUserList = new ArrayList<ChatUser>();
			serverSocket = new ServerSocket(ApplicationConstant.SERVER_PORT);
			chatServerConnectionList = new ArrayList<ChatServerConnection>();
		}
		catch (IOException ioEx)
		{
			System.out.println("\nUnable to set up port!");
			System.exit(1);
		}
		
		System.out.println("Server starts");
	}
/**
*  Client Connection Loop
*                (Setup of new socket, add Client to list, attach observer and start this client's Thread.  Creates a thread to handle 
*                 communication with each client and passes the constructor for this thread a reference to the relevant socket.... )
*/		
	public void start()
	{
		try
		{
			do
			{
				//Wait for client...
				Socket client = serverSocket.accept();
	
				System.out.println("\nNew client accepted.\n");
	
				//Create a thread to handle communication with
				//this client and pass the constructor for this
				//thread a reference to the relevant socket...
				ChatServerConnection chatConnection = new ChatServerConnection(client);				
				chatServerConnectionList.add(chatConnection);
				
				//add the chatServerController as an observer for the connection,
				//so when the chatConnection receives a message, it will notify the controller.
				chatConnection.addObserverChatServer(this);
				Thread t = new Thread(chatConnection);
				t.start();					
			}while (true);
		}
		catch(Exception ex)
		{
			System.err.println("Error when accepting new connection");
			ex.printStackTrace();
		}
	}
	/**
	* Add Client to list
	*/		
	public void updateChatUserList_add(ChatUser theChatUser)
	{
		chatUserList.add(theChatUser);
	}
	/**
	*   Remove client from list
	*/		
	public void updateChatUserList_remove(ChatUser theChatUser)
	{
		chatUserList.remove(theChatUser);
	}
	/**
	*   Message Output request
	*/		
	public void updateReceiveMessage(String message, ChatUser theChatSender)
	{
		broadcastMessage(message, theChatSender);
	}
	/**
	*   Message output
	*/		
	public void broadcastMessage(String message, ChatUser theChatSender)
	{
		for (ChatServerConnection connection:chatServerConnectionList)
		{
			connection.sendMessage(message);
		}
	}
}